package main.test.SparkAPI.Baics.classApi

/**
 * Implement functions and classes
 * Code using variables and values
 * Use if-else constructs
 * Implement a class, load it into the REPL, and interact with it.
 * present a vending machine that sells two products:
 * a white chocolate bar for $1.5 and granola bar for $1.
 * Let us keep things simple and assume that your application dosesnt give any change back.
 * A customer cna buy an item by selecting a specific product and inserting money into the vending machine.
 * Once the vending amchine receives the requeset, it
 * should check that the product is available and
 * the given money is enough; if all checks are
 * successful,
 * it should collect the money and release the product.
 * Let us analyze the business requirements and identify the main components of your
 * vending machine.
 */
class VendingMachine {
  /**
   * Let's define the api of yor vending machine and then focus on its implementation.
   * First, need to identify the main components of your vending machine, which
   * has a cash register containing the moneny collected so far and
   * a counter for each product type.
   * create a new file called VendingMachine.scala
   * and add the code below
   */


  /**
   * Counter of type Int because 0 is
   * a constant of type Int
   * Counter of type Double because 0.0 is a vlue of
   * type Double.
   */
  var chocolateBar = 0
  var granolaBar = 0

  var totalMoney = 0.0


  /**
   * Customs can perform one action: request a product by
   * giving moneny in exchange.
   * Let us define a  function called buy that
   * takes two parameters: a string for the product and
   * a Double for the money. Should return a human-readable message with the outcome of
   * the request.
   */
  def buy(product:String, money: Double):String = {
    /**
     * You can omit curly brackets here
     * because the function has an expression that contains only
     * one if-else construct.
     */
    if (!isProductAvaible(product))
      s"Sorry, product $product not available"
    else if (!isMoneyEnough(product, money))
      "Please insert more money"
    else completeRequest(product, money)
  }

  /**
   * also needs to perform the following operations:
   * 1 should check that the requested product is available.
   * 2 It should verify that the inserted money is sufficient.
   * 3 if all the validations are successful, it should complete it by collecting the money
   * and releasing the product.
   *
   *
   */
  def isProductAvaible(product:String):Boolean = {
    val productQuantity = {
      if (product == "chocolate") chocolateBar
      else if (product == "granola") granolaBar
        // any unknown product has zero quantity.
      else 0
    }
    productQuantity > 0
  }

  def isMoneyEnough(product:String,
                    money: Double):Boolean = {

    val cost = if (product == "chocolate") 1.5 else 1
    money >= cost
  }

  def completeRequest(product:String,
                      money:Double):String = {
    collectMoney(money)
    releaseProduct(product)
    s"There you go!Have a $product bar"

  }

  def collectMoney(money: Double) =
    totalMoney += money

  def releaseProduct(product: String) = {
    if (product == "chocolate") chocolateBar -= 1
    else if (product == "granola") granolaBar -= 1
  }

  /**
   * now you can implement the function buy.
   * All the pieces are connected! can now replace the occurrences of the
   * symbol ??? with a implementation.
   */

  /**
   * vending machine needs to check if the selected product is available and
   * if the money is enough for it to complete a customer request.
   * you have already defined how these functions should look,
   * but still need to implement them.
   *
   * If request is successful , vending machine should complete it by
   * collecting the money and releasing the selected product.
   *
   * now it is complete and ready to use!
   */
  /**
   * Possible improvements to our solution
   * congratulations on completing your first capstone!
   * Your vending machine implementation respects the given
   * requirements, but a few improvements are possible.
   * Let's see what these are and what techniques you'll learn to help improve your code.
   * Everything is publicly accessible variable and mehtods are visible and
   * modifiable without restrictions.Third parities could easily compromise the security of vending machine by
   * resetting counters and by overriding functions.
   * In Unit 2 , you will discover how to use access modifers to protect your code's sensitive information
   * from unwanted exposure and modification.
   *
   *
   * vars are problematic. you should avoid using var in your code.
   * limit their scope and use them only when utablility introduces an impressive perfomance increase.
   * Your program is incapable of dealing with multiple concurrent requests because of it
   * vars. What would happend if your vending machines has the resources to complete only one of
   * them ? what would happen if two calls for the same product arrive at precisely
   * the same time? unit 4 will learn about case classes and how they can help us overcome these issues by represnting data in an
   * immutable manner.
   * String as the representation of a product.
   * dosent provide any information about the products that the machine can offer.
   * Is the product no longer available or did the user just mistype its name
   * is it choco or chocolate is ChOcOlATe the same as chocolate? in
   * unit 2 ,you will see how to represnet a finite set of values using sealed traits and
   * objects.
   * String as return type.
   * not expressive enough.using an appropriate type
   * would give you a more explicit indication of the operation's result.
   * Suppose you need to execute some additonal computation depending on your program's outcome.
   * The only way to understand if the request was successful is to
   * interpret the returned text using a parser.
   * This approach is error prone and fragile because it is dependent on
   * the specific words used in returned messages.
   * Unit 6 will discover the types Try and Either  and how they can help you have
   * meaningful return values for computation.
   * The vending machine is not configurable.
   * Vending machine is not configurable: if you need to add a new product
   * to or change prices, you need the change your code.Unit 4 wil learn about data structures,
   * such as List and Map, and how you use them to abstract details like products and prices.
   *
   */

}
